[U-Boot] [PATCH 4/5] FSL SEC Driver : Add support for descriptor creation
Ruchika Gupta
ruchika.gupta at freescale.com
Thu Mar 28 11:46:34 CET 2013
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 at freescale.com>
Signed-off-by: Ruchika Gupta <ruchika.gupta at 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
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
--
1.7.7.6
More information about the U-Boot
mailing list