
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
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