Patchwork [U-Boot,4/5] FSL SEC Driver : Add support for descriptor creation

login
register
mail settings
Submitter Ruchika Gupta
Date March 28, 2013, 10:46 a.m.
Message ID <1364467595-15539-5-git-send-email-ruchika.gupta@freescale.com>
Download mbox | patch
Permalink /patch/231978/
State Changes Requested
Delegated to: York Sun
Headers show

Comments

Ruchika Gupta - March 28, 2013, 10:46 a.m.
The patch add supports for descriptor creation for doing
1.SHA256 and RSA Modular exponentiation.
2. Cryptographic blob encryption/decryption

Following files have been picked up from caam driver in Linux :
        drivers/sec/error.c
        include/desc_constr.h

Signed-off-by: Kuldip Giroh <kuldip.giroh@freescale.com>
Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
---
Based upon git://git.denx.de/u-boot.git branch master

 drivers/sec/Makefile  |    2 +-
 drivers/sec/error.c   |  259 +++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/sec/jobdesc.c |  157 ++++++++++++++++++++++++++++++
 drivers/sec/rsa_sec.c |   95 ++++++++++++++++++
 drivers/sec/sha.c     |  111 +++++++++++++++++++++
 include/desc_constr.h |  200 ++++++++++++++++++++++++++++++++++++++
 include/jobdesc.h     |   55 +++++++++++
 include/rsa_sec.h     |   59 +++++++++++
 include/sha.h         |  100 +++++++++++++++++++
 9 files changed, 1037 insertions(+), 1 deletions(-)
 create mode 100644 drivers/sec/error.c
 create mode 100644 drivers/sec/jobdesc.c
 create mode 100644 drivers/sec/rsa_sec.c
 create mode 100644 drivers/sec/sha.c
 create mode 100644 include/desc_constr.h
 create mode 100644 include/jobdesc.h
 create mode 100644 include/rsa_sec.h
 create mode 100644 include/sha.h

Patch

diff --git a/drivers/sec/Makefile b/drivers/sec/Makefile
index 33c707e..01eafba 100644
--- a/drivers/sec/Makefile
+++ b/drivers/sec/Makefile
@@ -25,7 +25,7 @@  include $(TOPDIR)/config.mk
 
 LIB	:= $(obj)libsec.o
 
-COBJS-$(CONFIG_SECURE_BOOT) += jr.o
+COBJS-$(CONFIG_SECURE_BOOT) += jr.o jobdesc.o sha.o rsa_sec.o error.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/sec/error.c b/drivers/sec/error.c
new file mode 100644
index 0000000..f8bd273
--- /dev/null
+++ b/drivers/sec/error.c
@@ -0,0 +1,259 @@ 
+/*
+ * CAAM Error Reporting
+ *
+ * Copyright 2009-2012 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <jr.h>
+#include <malloc.h>
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define JRSTA_SSRC_SHIFT            28
+#define JRSTA_CCBERR_CHAID_MASK     0x00f0
+#define JRSTA_CCBERR_CHAID_SHIFT    4
+#define JRSTA_CCBERR_ERRID_MASK     0x000
+
+#define JRSTA_DECOERR_JUMP          0x08000000
+#define JRSTA_DECOERR_INDEX_SHIFT   8
+#define JRSTA_DECOERR_INDEX_MASK    0xff00
+#define JRSTA_DECOERR_ERROR_MASK    0x00ff
+
+#define SPRINTFCAT(str, format, param, max_alloc)		\
+{								\
+	char *tmp;						\
+								\
+	tmp = malloc(sizeof(format) + max_alloc);		\
+	sprintf(tmp, format, param);				\
+	strcat(str, tmp);					\
+	free(tmp);						\
+}
+
+static void report_jump_idx(u32 status, char *outstr)
+{
+	u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
+		  JRSTA_DECOERR_INDEX_SHIFT;
+
+	if (status & JRSTA_DECOERR_JUMP)
+		strcat(outstr, "jump tgt desc idx ");
+	else
+		strcat(outstr, "desc idx ");
+
+	SPRINTFCAT(outstr, "%d: ", idx, sizeof("255"));
+}
+
+static void report_ccb_status(u32 status, char *outstr)
+{
+	char *cha_id_list[] = {
+		"",
+		"AES",
+		"DES, 3DES",
+		"ARC4",
+		"MD5, SHA-1, SH-224, SHA-256, SHA-384, SHA-512",
+		"RNG",
+		"SNOW f8",
+		"Kasumi f8, f9",
+		"All Public Key Algorithms",
+		"CRC",
+		"SNOW f9",
+	};
+	char *err_id_list[] = {
+		"None. No error.",
+		"Mode error.",
+		"Data size error.",
+		"Key size error.",
+		"PKHA A memory size error.",
+		"PKHA B memory size error.",
+		"Data arrived out of sequence error.",
+		"PKHA divide-by-zero error.",
+		"PKHA modulus even error.",
+		"DES key parity error.",
+		"ICV check failed.",
+		"Hardware error.",
+		"Unsupported CCM AAD size.",
+		"Class 1 CHA is not reset",
+		"Invalid CHA combination was selected",
+		"Invalid CHA selected.",
+	};
+	u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >>
+		    JRSTA_CCBERR_CHAID_SHIFT;
+	u8 err_id = status & JRSTA_CCBERR_ERRID_MASK;
+
+	report_jump_idx(status, outstr);
+
+	if (cha_id < ARRAY_SIZE(cha_id_list)) {
+		SPRINTFCAT(outstr, "%s: ", cha_id_list[cha_id],
+			   strlen(cha_id_list[cha_id]));
+	} else {
+		SPRINTFCAT(outstr, "unidentified cha_id value 0x%02x: ",
+			   cha_id, sizeof("ff"));
+	}
+
+	if (err_id < ARRAY_SIZE(err_id_list)) {
+		SPRINTFCAT(outstr, "%s", err_id_list[err_id],
+			   strlen(err_id_list[err_id]));
+	} else {
+		SPRINTFCAT(outstr, "unidentified err_id value 0x%02x",
+			   err_id, sizeof("ff"));
+	}
+}
+
+static void report_jump_status(u32 status, char *outstr)
+{
+	SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__));
+}
+
+static void report_deco_status(u32 status, char *outstr)
+{
+	const struct {
+		u8 value;
+		char *error_text;
+	} desc_error_list[] = {
+		{ 0x00, "None. No error." },
+		{ 0x01, "SGT Length Error. The descriptor is trying to read "
+			"more data than is contained in the SGT table." },
+		{ 0x02, "Reserved." },
+		{ 0x03, "Job Ring Control Error. There is a bad value in the "
+			"Job Ring Control register." },
+		{ 0x04, "Invalid Descriptor Command. The Descriptor Command "
+			"field is invalid." },
+		{ 0x05, "Reserved." },
+		{ 0x06, "Invalid KEY Command" },
+		{ 0x07, "Invalid LOAD Command" },
+		{ 0x08, "Invalid STORE Command" },
+		{ 0x09, "Invalid OPERATION Command" },
+		{ 0x0A, "Invalid FIFO LOAD Command" },
+		{ 0x0B, "Invalid FIFO STORE Command" },
+		{ 0x0C, "Invalid MOVE Command" },
+		{ 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is "
+			"invalid because the target is not a Job Header "
+			"Command, or the jump is from a Trusted Descriptor to "
+			"a Job Descriptor, or because the target Descriptor "
+			"contains a Shared Descriptor." },
+		{ 0x0E, "Invalid MATH Command" },
+		{ 0x0F, "Invalid SIGNATURE Command" },
+		{ 0x10, "Invalid Sequence Command. A SEQ IN PTR OR SEQ OUT PTR "
+			"Command is invalid or a SEQ KEY, SEQ LOAD, SEQ FIFO "
+			"LOAD, or SEQ FIFO STORE decremented the input or "
+			"output sequence length below 0. This error may result "
+			"if a built-in PROTOCOL Command has encountered a "
+			"malformed PDU." },
+		{ 0x11, "Skip data type invalid. The type must be 0xE or 0xF."},
+		{ 0x12, "Shared Descriptor Header Error" },
+		{ 0x13, "Header Error. Invalid length or parity, or certain "
+			"other problems." },
+		{ 0x14, "Burster Error. Burster has gotten to an illegal "
+			"state" },
+		{ 0x15, "Context Register Length Error. The descriptor is "
+			"trying to read or write past the end of the Context "
+			"Register. A SEQ LOAD or SEQ STORE with the VLF bit "
+			"set was executed with too large a length in the "
+			"variable length register (VSOL for SEQ STORE or VSIL "
+			"for SEQ LOAD)." },
+		{ 0x16, "DMA Error" },
+		{ 0x17, "Reserved." },
+		{ 0x1A, "Job failed due to JR reset" },
+		{ 0x1B, "Job failed due to Fail Mode" },
+		{ 0x1C, "DECO Watchdog timer timeout error" },
+		{ 0x1D, "DECO tried to copy a key from another DECO but the "
+			"other DECO's Key Registers were locked" },
+		{ 0x1E, "DECO attempted to copy data from a DECO that had an "
+			"unmasked Descriptor error" },
+		{ 0x1F, "LIODN error. DECO was trying to share from itself or "
+			"from another DECO but the two Non-SEQ LIODN values "
+			"didn't match or the 'shared from' DECO's Descriptor "
+			"required that the SEQ LIODNs be the same and they "
+			"aren't." },
+		{ 0x20, "DECO has completed a reset initiated via the DRR "
+			"register" },
+		{ 0x21, "Nonce error. When using EKT (CCM) key encryption "
+			"option in the FIFO STORE Command, the Nonce counter "
+			"reached its maximum value and this encryption mode "
+			"can no longer be used." },
+		{ 0x22, "Meta data is too large (> 511 bytes) for TLS decap "
+			"(input frame; block ciphers) and IPsec decap (output "
+			"frame, when doing the next header byte update) and "
+			"DCRC (output frame)." },
+		{ 0x80, "DNR (do not run) error" },
+		{ 0x81, "undefined protocol command" },
+		{ 0x82, "invalid setting in PDB" },
+		{ 0x83, "Anti-replay LATE error" },
+		{ 0x84, "Anti-replay REPLAY error" },
+		{ 0x85, "Sequence number overflow" },
+		{ 0x86, "Sigver invalid signature" },
+		{ 0x87, "DSA Sign Illegal test descriptor" },
+		{ 0x88, "Protocol Format Error - A protocol has seen an error "
+			"in the format of data received. When running RSA, "
+			"this means that formatting with random padding was "
+			"used, and did not follow the form: 0x00, 0x02, 8-to-N "
+			"bytes of non-zero pad, 0x00, F data." },
+		{ 0x89, "Protocol Size Error - A protocol has seen an error in "
+			"size. When running RSA, pdb size N < (size of F) when "
+			"no formatting is used; or pdb size N < (F + 11) when "
+			"formatting is used." },
+		{ 0xC1, "Blob Command error: Undefined mode" },
+		{ 0xC2, "Blob Command error: Secure Memory Blob mode error" },
+		{ 0xC4, "Blob Command error: Black Blob key or input size "
+			"error" },
+		{ 0xC5, "Blob Command error: Invalid key destination" },
+		{ 0xC8, "Blob Command error: Trusted/Secure mode error" },
+		{ 0xF0, "IPsec TTL or hop limit field either came in as 0, "
+			"or was decremented to 0" },
+		{ 0xF1, "3GPP HFN matches or exceeds the Threshold" },
+	};
+	u8 desc_error = status & JRSTA_DECOERR_ERROR_MASK;
+	int i;
+
+	report_jump_idx(status, outstr);
+
+	for (i = 0; i < ARRAY_SIZE(desc_error_list); i++)
+		if (desc_error_list[i].value == desc_error)
+			break;
+
+	if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text) {
+		SPRINTFCAT(outstr, "%s", desc_error_list[i].error_text,
+			   strlen(desc_error_list[i].error_text));
+	} else {
+		SPRINTFCAT(outstr, "unidentified error value 0x%02x",
+			   desc_error, sizeof("ff"));
+	}
+}
+
+static void report_jr_status(u32 status, char *outstr)
+{
+}
+
+static void report_cond_code_status(u32 status, char *outstr)
+{
+	SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__));
+}
+
+int caam_jr_strstatus(char *outstr, u32 status)
+{
+	int ret = 0;
+	struct stat_src {
+		void (*report_ssed)(u32 status, char *outstr);
+		char *error;
+	} status_src[] = {
+		{ NULL, "No error" },
+		{ NULL, NULL },
+		{ report_ccb_status, "CCB" },
+		{ report_jump_status, "Jump" },
+		{ report_deco_status, "DECO" },
+		{ NULL, NULL },
+		{ report_jr_status, "Job Ring" },
+		{ report_cond_code_status, "Condition Code" },
+	};
+	u32 ssrc = status >> JRSTA_SSRC_SHIFT;
+
+	sprintf(outstr, "%s: ", status_src[ssrc].error);
+
+	if (status_src[ssrc].report_ssed) {
+		status_src[ssrc].report_ssed(status, outstr);
+		ret = -1;
+	} else
+		ret = 0;
+
+	return ret;
+}
diff --git a/drivers/sec/jobdesc.c b/drivers/sec/jobdesc.c
new file mode 100644
index 0000000..21b4017
--- /dev/null
+++ b/drivers/sec/jobdesc.c
@@ -0,0 +1,157 @@ 
+/*
+ * SEC Descriptor Construction Library
+ * Basic job descriptor construction
+ *
+ * Copyright (c) 2012 Freescale Semiconductor, Inc.
+ * All Rights Reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <common.h>
+#include <desc_constr.h>
+#include <jobdesc.h>
+
+void inline_cnstr_jobdesc_blob_encrypt(uint32_t *desc, uint8_t *key_idnfr,
+		 uint32_t keysz, uint8_t *plain_txt, uint8_t *enc_blob,
+					uint32_t in_sz, uint32_t out_sz)
+{
+
+	dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
+	uint32_t key_sz = 16 ;
+
+	dma_addr_key_idnfr = virt_to_phys((void *)key_idnfr);
+	dma_addr_in	= virt_to_phys((void *)plain_txt);
+	dma_addr_out	= virt_to_phys((void *)enc_blob);
+
+	init_job_desc(desc, 0);
+	append_key(desc, dma_addr_key_idnfr, key_sz, CLASS_2);
+
+	if (in_sz > 0xffff) {
+		append_seq_in_ptr(desc, dma_addr_in, 0, SQIN_EXT);
+		append_cmd(desc, in_sz);
+	} else {
+		append_seq_in_ptr(desc, dma_addr_in, in_sz, 0);
+	}
+
+	if (out_sz > 0xffff) {
+		append_seq_out_ptr(desc, dma_addr_out, 0, SQOUT_EXT);
+		append_cmd(desc, out_sz);
+	} else {
+		append_seq_out_ptr(desc, dma_addr_out, out_sz, 0);
+	}
+	append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB);
+}
+
+void inline_cnstr_jobdesc_blob_decrypt(uint32_t *desc, uint8_t *key_idnfr,
+			uint32_t keysz, uint8_t *enc_blob, uint8_t *plain_txt,
+					      uint32_t in_sz, uint32_t out_sz)
+{
+	dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
+	uint32_t key_sz = 16 ;
+
+	dma_addr_key_idnfr = virt_to_phys((void *)key_idnfr);
+	dma_addr_in	= virt_to_phys((void *)enc_blob);
+	dma_addr_out	= virt_to_phys((void *)plain_txt);
+
+	init_job_desc(desc, 0);
+	append_key(desc, dma_addr_key_idnfr, key_sz, CLASS_2);
+	if (in_sz > 0xffff) {
+		append_seq_in_ptr(desc, dma_addr_in, 0, SQIN_EXT);
+		append_cmd(desc, in_sz);
+	} else {
+		append_seq_in_ptr(desc, dma_addr_in, in_sz, 0);
+	}
+
+	if (out_sz > 0xffff) {
+		append_seq_out_ptr(desc, dma_addr_out, 0, SQOUT_EXT);
+		append_cmd(desc, out_sz);
+	} else {
+		append_seq_out_ptr(desc, dma_addr_out, out_sz, 0);
+	}
+
+	append_operation(desc, OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB);
+}
+
+
+/* Change key size to bytes form bits in calling function*/
+void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
+				      struct pk_in_params *pkin, uint8_t *out,
+				      uint32_t out_siz)
+{
+	dma_addr_t dma_addr_e, dma_addr_a, dma_addr_n, dma_addr_out;
+
+	dma_addr_e = virt_to_phys((void *)pkin->e);
+	dma_addr_a = virt_to_phys((void *)pkin->a);
+	dma_addr_n = virt_to_phys((void *)pkin->n);
+	dma_addr_out = virt_to_phys((void *)out);
+
+	init_job_desc(desc, 0);
+	append_key(desc, dma_addr_e, pkin->e_siz, KEY_DEST_PKHA_E | CLASS_1);
+
+	append_fifo_load(desc, dma_addr_a,
+			 pkin->a_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_A);
+
+	append_fifo_load(desc, dma_addr_n,
+			 pkin->n_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_N);
+
+	append_operation(desc, OP_TYPE_PK | OP_ALG_PK | OP_ALG_PKMODE_MOD_EXPO);
+
+	append_fifo_store(desc, dma_addr_out, out_siz,
+			  LDST_CLASS_1_CCB | FIFOST_TYPE_PKHA_B);
+}
+
+void inline_cnstr_jobdesc_sha256(uint32_t *desc,
+				 uint8_t *msg, uint32_t msgsz,
+				 uint8_t *digest)
+{
+	/* SHA 256 , output is of length 32 words */
+	uint32_t storelen = 32;
+	dma_addr_t dma_addr_in, dma_addr_out;
+
+	dma_addr_in = virt_to_phys((void *)msg);
+	dma_addr_out = virt_to_phys((void *)digest);
+
+	init_job_desc(desc, 0);
+	append_operation(desc,
+			 OP_TYPE_CLASS2_ALG | OP_ALG_ALGSEL_SHA256 |
+			 OP_ALG_AAI_HASH | OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT
+			 | OP_ALG_ICV_OFF);
+	if (msgsz > 0xffff) {
+		append_fifo_load(desc, dma_addr_in, 0,
+				 LDST_CLASS_2_CCB | FIFOLDST_SGF |
+				 FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2 |
+				 FIFOLDST_EXT);
+		append_cmd(desc, msgsz);
+	} else
+		append_fifo_load(desc, dma_addr_in, msgsz,
+				 LDST_CLASS_2_CCB | FIFOLDST_SGF |
+				 FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2);
+	append_store(desc, dma_addr_out, storelen,
+		     LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT);
+}
diff --git a/drivers/sec/rsa_sec.c b/drivers/sec/rsa_sec.c
new file mode 100644
index 0000000..6e114aa
--- /dev/null
+++ b/drivers/sec/rsa_sec.c
@@ -0,0 +1,95 @@ 
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * All Rights Reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <common.h>
+#include <rsa_sec.h>
+#include <jobdesc.h>
+
+extern struct jobring jr;
+
+void rsa_done(uint32_t desc, uint32_t status, void *arg)
+{
+	struct result *x = arg;
+	x->status = status;
+#ifdef DEBUG
+	x->err = caam_jr_strstatus(x->outstr, status);
+#else
+	if (status)
+		x->err = -1;
+#endif
+
+	x->done = 1;
+}
+
+/* This functionw ould return teh status returned by SEC .
+ * If non zero , means there was some error reported by SEC */
+int rsa_public_verif_sec(unsigned char *sign, uint8_t *to, uint8_t *rsa_pub_key,
+			int klen, struct rsa_context *ctx)
+{
+	unsigned long long timeval;
+	unsigned long long timeout;
+	int ret = 0;
+	memset(ctx, 0, sizeof(struct rsa_context));
+
+	ctx->pkin.a = sign;
+	ctx->pkin.a_siz = klen;
+	ctx->pkin.n = rsa_pub_key;
+	ctx->pkin.n_siz = klen;
+	ctx->pkin.e = rsa_pub_key + klen;
+	ctx->pkin.e_siz = klen;
+
+	inline_cnstr_jobdesc_pkha_rsaexp(ctx->rsa_desc,
+			      &ctx->pkin, to,
+			      klen);
+
+	ret = jr_enqueue(&jr, ctx->rsa_desc, rsa_done, &ctx->op);
+	if (ret)
+		return ret;
+
+	timeval = get_ticks();
+	timeout = usec2ticks(CONFIG_SEC_DEQ_TIMEOUT);
+
+	while (ctx->op.done != 1) {
+		if (jr_dequeue(&jr))
+			return JQ_DEQ_ERR;
+
+		if ((get_ticks() - timeval) > timeout) {
+			printf("SEC Dequeue timed out\n");
+			return JQ_DEQ_TO_ERR;
+		}
+	}
+
+	if (ctx->op.err < 0)
+		return ctx->op.status;
+
+	return 0;
+}
diff --git a/drivers/sec/sha.c b/drivers/sec/sha.c
new file mode 100644
index 0000000..4bbae65
--- /dev/null
+++ b/drivers/sec/sha.c
@@ -0,0 +1,111 @@ 
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * All Rights Reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <common.h>
+#include <jobdesc.h>
+#include <sha.h>
+
+extern struct jobring jr;
+
+void sha_done(uint32_t desc, uint32_t status, void *arg)
+{
+	struct result *x = arg;
+	x->status = status;
+	x->err = caam_jr_strstatus(x->outstr, status);
+	x->done = 1;
+}
+
+/* This function initializes the sha-256 context */
+void sha_init(struct sha_ctx *ctx)
+{
+	memset(ctx, 0, sizeof(struct sha_ctx));
+	ctx->jr = &jr;
+}
+
+void sha_update(struct sha_ctx *ctx, u8 *buffer, u32 length)
+{
+	dma_addr_t addr = virt_to_phys((void *)buffer);
+#ifdef CONFIG_PHYS_64BIT
+	ctx->sg_tbl[ctx->sg_num].addr_hi = addr >> 32;
+#else
+	ctx->sg_tbl[ctx->sg_num].addr_hi = 0x0;
+#endif
+	ctx->sg_tbl[ctx->sg_num].addr_lo = addr;
+	ctx->sg_tbl[ctx->sg_num].length = length;
+	ctx->sg_num++;
+}
+
+int sha_final(struct sha_ctx *ctx)
+{
+	int ret = 0, i = 0;
+	ctx->sg_tbl[ctx->sg_num - 1].final = 1;
+	uint32_t len = 0;
+
+	for (i = 0; i < ctx->sg_num; i++)
+		len +=  ctx->sg_tbl[i].length;
+
+	inline_cnstr_jobdesc_sha256(ctx->sha_desc,
+			   (uint8_t *)ctx->sg_tbl, len, ctx->hash);
+
+	ret = jr_enqueue(ctx->jr, ctx->sha_desc, sha_done, &ctx->op);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+
+/* This  function  completes the calulation of the sha-256 */
+int sha_digest(struct sha_ctx *ctx, uint8_t *digest)
+{
+	unsigned long long timeval = get_ticks();
+	unsigned long long timeout = usec2ticks(CONFIG_SEC_DEQ_TIMEOUT);
+	int ret = 0;
+
+	while (ctx->op.done != 1) {
+		ret = jr_dequeue(ctx->jr);
+		if (ret)
+			return ret;
+
+		if ((get_ticks() - timeval) > timeout) {
+			printf("SEC Dequeue timed out\n");
+			return JQ_DEQ_TO_ERR;
+		}
+	}
+
+	if (ctx->op.err < 0)
+		return ctx->op.status;
+
+	memcpy(digest, ctx->hash, sizeof(ctx->hash));
+
+	return 0;
+}
diff --git a/include/desc_constr.h b/include/desc_constr.h
new file mode 100644
index 0000000..e3e778f
--- /dev/null
+++ b/include/desc_constr.h
@@ -0,0 +1,200 @@ 
+/*
+ * caam descriptor construction helper functions
+ *
+ * Copyright 2008-2011, 2012 Freescale Semiconductor, Inc.
+ */
+
+#include "desc.h"
+
+#define IMMEDIATE (1 << 23)
+#define CAAM_CMD_SZ sizeof(u32)
+#define CAAM_PTR_SZ sizeof(dma_addr_t)
+#define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * 64)
+
+#define PRINT_POS
+
+#define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
+				LDST_SRCDST_WORD_DECOCTRL | \
+				(LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
+#define ENABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
+			       LDST_SRCDST_WORD_DECOCTRL | \
+			       (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
+
+static inline int desc_len(u32 *desc)
+{
+	return *desc & HDR_DESCLEN_MASK;
+}
+
+static inline int desc_bytes(void *desc)
+{
+	return desc_len(desc) * CAAM_CMD_SZ;
+}
+
+static inline u32 *desc_end(u32 *desc)
+{
+	return desc + desc_len(desc);
+}
+
+static inline void *sh_desc_pdb(u32 *desc)
+{
+	return desc + 1;
+}
+
+static inline void init_desc(u32 *desc, u32 options)
+{
+	*desc = options | HDR_ONE | 1;
+}
+
+static inline void init_sh_desc(u32 *desc, u32 options)
+{
+	PRINT_POS;
+	init_desc(desc, CMD_SHARED_DESC_HDR | options);
+}
+
+static inline void init_sh_desc_pdb(u32 *desc, u32 options, size_t pdb_bytes)
+{
+	u32 pdb_len = pdb_bytes / CAAM_CMD_SZ + 1;
+
+	init_sh_desc(desc, ((pdb_len << HDR_START_IDX_SHIFT) + pdb_len) |
+		     options);
+}
+
+static inline void init_job_desc(u32 *desc, u32 options)
+{
+	init_desc(desc, CMD_DESC_HDR | options);
+}
+
+static inline void append_ptr(u32 *desc, dma_addr_t ptr)
+{
+	dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
+
+	*offset = ptr;
+
+	(*desc) += CAAM_PTR_SZ / CAAM_CMD_SZ;
+}
+
+static inline void init_job_desc_shared(u32 *desc, dma_addr_t ptr, int len,
+					u32 options)
+{
+	PRINT_POS;
+	init_job_desc(desc, HDR_SHARED | options |
+		      (len << HDR_START_IDX_SHIFT));
+	append_ptr(desc, ptr);
+}
+
+static inline void append_data(u32 *desc, void *data, int len)
+{
+	u32 *offset = desc_end(desc);
+
+	if (len) /* avoid sparse warning: memcpy with byte count of 0 */
+		memcpy(offset, data, len);
+
+	(*desc) += (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
+}
+
+static inline void append_cmd(u32 *desc, u32 command)
+{
+	u32 *cmd = desc_end(desc);
+
+	*cmd = command;
+
+	(*desc)++;
+}
+
+static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len,
+				  u32 command)
+{
+	append_cmd(desc, command | len);
+	append_ptr(desc, ptr);
+}
+
+static inline void append_cmd_data(u32 *desc, void *data, int len,
+				   u32 command)
+{
+	append_cmd(desc, command | IMMEDIATE | len);
+	append_data(desc, data, len);
+}
+
+static inline u32 *append_jump(u32 *desc, u32 options)
+{
+	u32 *cmd = desc_end(desc);
+
+	PRINT_POS;
+	append_cmd(desc, CMD_JUMP | options);
+
+	return cmd;
+}
+
+static inline void set_jump_tgt_here(u32 *desc, u32 *jump_cmd)
+{
+	*jump_cmd = *jump_cmd | (desc_len(desc) - (jump_cmd - desc));
+}
+
+#define APPEND_CMD(cmd, op) \
+static inline void append_##cmd(u32 *desc, u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd(desc, CMD_##op | options); \
+}
+APPEND_CMD(operation, OPERATION)
+APPEND_CMD(move, MOVE)
+
+#define APPEND_CMD_LEN(cmd, op) \
+static inline void append_##cmd(u32 *desc, unsigned int len, u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd(desc, CMD_##op | len | options); \
+}
+APPEND_CMD_LEN(seq_store, SEQ_STORE)
+APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
+APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
+
+#define APPEND_CMD_PTR(cmd, op) \
+static inline void append_##cmd(u32 *desc, dma_addr_t ptr, unsigned int len, \
+				u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd_ptr(desc, ptr, len, CMD_##op | options); \
+}
+APPEND_CMD_PTR(key, KEY)
+APPEND_CMD_PTR(seq_in_ptr, SEQ_IN_PTR)
+APPEND_CMD_PTR(seq_out_ptr, SEQ_OUT_PTR)
+APPEND_CMD_PTR(load, LOAD)
+APPEND_CMD_PTR(store, STORE)
+APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
+APPEND_CMD_PTR(fifo_store, FIFO_STORE)
+
+#define APPEND_CMD_PTR_TO_IMM(cmd, op) \
+static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
+					 unsigned int len, u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd_data(desc, data, len, CMD_##op | options); \
+}
+APPEND_CMD_PTR_TO_IMM(load, LOAD);
+APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
+
+/*
+ * 2nd variant for commands whose specified immediate length differs
+ * from length of immediate data provided, e.g., split keys
+ */
+#define APPEND_CMD_PTR_TO_IMM2(cmd, op) \
+static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
+					 unsigned int data_len, \
+					 unsigned int len, u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd(desc, CMD_##op | IMMEDIATE | len | options); \
+	append_data(desc, data, data_len); \
+}
+APPEND_CMD_PTR_TO_IMM2(key, KEY);
+
+#define APPEND_CMD_RAW_IMM(cmd, op, type) \
+static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \
+					     u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \
+	append_cmd(desc, immediate); \
+}
+APPEND_CMD_RAW_IMM(load, LOAD, u32);
diff --git a/include/jobdesc.h b/include/jobdesc.h
new file mode 100644
index 0000000..6eb2827
--- /dev/null
+++ b/include/jobdesc.h
@@ -0,0 +1,55 @@ 
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * All Rights Reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __JOBDESC_H
+#define __JOBDESC_H
+
+#include <common.h>
+#include <sha.h>
+#include <rsa_sec.h>
+
+void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
+			      struct pk_in_params *pkin, uint8_t *out,
+			      uint32_t out_siz);
+
+void inline_cnstr_jobdesc_sha256(uint32_t *desc,
+	uint8_t *msg, uint32_t msgsz, uint8_t *digest);
+
+void inline_cnstr_jobdesc_blob_encrypt(uint32_t *desc, uint8_t *key_idnfr,
+	uint32_t keysz, uint8_t *plain_txt, uint8_t *enc_blob, uint32_t in_sz,
+	uint32_t out_sz);
+
+void inline_cnstr_jobdesc_blob_decrypt(uint32_t *desc, uint8_t *key_idnfr,
+	uint32_t keysz, uint8_t *plain_txt, uint8_t *enc_blob, uint32_t in_sz,
+	uint32_t out_sz);
+
+#endif
diff --git a/include/rsa_sec.h b/include/rsa_sec.h
new file mode 100644
index 0000000..1f6e218
--- /dev/null
+++ b/include/rsa_sec.h
@@ -0,0 +1,59 @@ 
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * All Rights Reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __RSA_SEC_H
+#define __RSA_SEC_H
+
+#include <common.h>
+#include <jr.h>
+
+struct pk_in_params {
+	uint8_t *e;
+	uint32_t e_siz;
+	uint8_t *n;
+	uint32_t n_siz;
+	uint8_t *a;
+	uint32_t a_siz;
+	uint8_t *b;
+	uint32_t b_siz;
+};
+
+struct rsa_context {
+	struct pk_in_params pkin;
+	uint32_t rsa_desc[64];
+	struct result op;
+};
+
+int rsa_public_verif_sec(unsigned char *sign, uint8_t *to, uint8_t *rsa_pub_key,
+			int klen, struct rsa_context *ctx);
+
+#endif
diff --git a/include/sha.h b/include/sha.h
new file mode 100644
index 0000000..ea4c4c8
--- /dev/null
+++ b/include/sha.h
@@ -0,0 +1,100 @@ 
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * All Rights Reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SHA_H
+#define _SHA_H
+
+#include <jr.h>
+
+/* number of bytes in the SHA256-256 digest */
+#define SHA256_DIGEST_SIZE 32
+
+/*
+ * number of words in the digest - Digest is kept internally
+ * as 8 32-bit words
+ */
+#define _SHA256_DIGEST_LENGTH 8
+
+/*
+ * block length - A block, treated as a sequence of
+ * 32-bit words
+ */
+#define SHA256_BLOCK_LENGTH 16
+
+/* number of bytes in the block */
+#define SHA256_DATA_SIZE 64
+
+#define MAX_SG		12
+
+/*
+ * Scatter Gather Entry - Speicifies the the Scatter Gather Format
+ * related information
+ */
+struct sg_entry {
+	uint16_t reserved_zero;
+	uint16_t addr_hi;	/* Memory Address of the start of the
+				 * buffer - hi
+				 */
+	uint32_t addr_lo;	/* Memory Address - lo */
+	unsigned int extension:1;
+	unsigned int final:1;
+	unsigned int length:30;	/* Length of the data in the frame */
+	uint8_t reserved_zero2;
+	uint8_t bpid;		/* Buffer Pool Id */
+	unsigned int reserved_offset:3;
+	unsigned int offset:13;
+};
+
+/*
+ * SHA256-256 context
+ * contain the following fields
+ * State
+ * count low
+ * count high
+ * block data buffer
+ * index to the buffer
+ */
+struct sha_ctx {
+	struct sg_entry sg_tbl[MAX_SG];
+	uint32_t sha_desc[64];
+	u8 hash[SHA256_DIGEST_SIZE];
+	struct result op;
+	uint32_t sg_num;
+	struct jobring *jr;
+};
+
+void sha_init(struct sha_ctx *ctx);
+void sha_update(struct sha_ctx *ctx, uint8_t *data, uint32_t length);
+int sha_final(struct sha_ctx *ctx);
+int sha_digest(struct sha_ctx *ctx, uint8_t *digest);
+
+#endif