Commit 94e3c8c4fd7bfe395fa467973cd647551d6d98c7

Authored by gaurav rana
Committed by York Sun
1 parent 7ee8c4795d

crypto/fsl - Add progressive hashing support using hardware acceleration.

Currently only normal hashing is supported using hardware acceleration.
Added support for progressive hashing using hardware.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
Signed-off-by: Gaurav Rana <gaurav.rana@freescale.com>
CC: Simon Glass <sjg@chromium.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: York Sun <yorksun@freescale.com>

Showing 8 changed files with 302 additions and 7 deletions Side-by-side Diff

... ... @@ -141,7 +141,9 @@
141 141 select RSA
142 142 help
143 143 This option enables signature verification of FIT uImages,
144   - using a hash signed and verified using RSA.
  144 + using a hash signed and verified using RSA. If
  145 + CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive
  146 + hashing is available using hardware, RSA library will use it.
145 147 See doc/uImage.FIT/signature.txt for more details.
146 148  
147 149 config SYS_EXTRA_OPTIONS
... ... @@ -3152,8 +3152,18 @@
3152 3152 Enable the hash verify command (hash -v). This adds to code
3153 3153 size a little.
3154 3154  
3155   - CONFIG_SHA1 - support SHA1 hashing
3156   - CONFIG_SHA256 - support SHA256 hashing
  3155 + CONFIG_SHA1 - This option enables support of hashing using SHA1
  3156 + algorithm. The hash is calculated in software.
  3157 + CONFIG_SHA256 - This option enables support of hashing using
  3158 + SHA256 algorithm. The hash is calculated in software.
  3159 + CONFIG_SHA_HW_ACCEL - This option enables hardware acceleration
  3160 + for SHA1/SHA256 hashing.
  3161 + This affects the 'hash' command and also the
  3162 + hash_lookup_algo() function.
  3163 + CONFIG_SHA_PROG_HW_ACCEL - This option enables
  3164 + hardware-acceleration for SHA1/SHA256 progressive hashing.
  3165 + Data can be streamed in a block at a time and the hashing
  3166 + is performed in hardware.
3157 3167  
3158 3168 Note: There is also a sha1sum command, which should perhaps
3159 3169 be deprecated in favour of 'hash sha1'.
... ... @@ -3447,8 +3457,10 @@
3447 3457  
3448 3458 CONFIG_FIT_SIGNATURE
3449 3459 This option enables signature verification of FIT uImages,
3450   - using a hash signed and verified using RSA. See
3451   - doc/uImage.FIT/signature.txt for more details.
  3460 + using a hash signed and verified using RSA. If
  3461 + CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive
  3462 + hashing is available using hardware, RSA library will use it.
  3463 + See doc/uImage.FIT/signature.txt for more details.
3452 3464  
3453 3465 WARNING: When relying on signed FIT images with required
3454 3466 signature check the legacy image format is default
... ... @@ -127,11 +127,21 @@
127 127 SHA1_SUM_LEN,
128 128 hw_sha1,
129 129 CHUNKSZ_SHA1,
  130 +#ifdef CONFIG_SHA_PROG_HW_ACCEL
  131 + hw_sha_init,
  132 + hw_sha_update,
  133 + hw_sha_finish,
  134 +#endif
130 135 }, {
131 136 "sha256",
132 137 SHA256_SUM_LEN,
133 138 hw_sha256,
134 139 CHUNKSZ_SHA256,
  140 +#ifdef CONFIG_SHA_PROG_HW_ACCEL
  141 + hw_sha_init,
  142 + hw_sha_update,
  143 + hw_sha_finish,
  144 +#endif
135 145 },
136 146 #endif
137 147 #ifdef CONFIG_SHA1
drivers/crypto/fsl/fsl_hash.c
... ... @@ -10,6 +10,9 @@
10 10 #include "jobdesc.h"
11 11 #include "desc.h"
12 12 #include "jr.h"
  13 +#include "fsl_hash.h"
  14 +#include <hw_sha.h>
  15 +#include <asm-generic/errno.h>
13 16  
14 17 #define CRYPTO_MAX_ALG_NAME 80
15 18 #define SHA1_DIGEST_SIZE 20
... ... @@ -39,6 +42,122 @@
39 42 },
40 43 };
41 44  
  45 +static enum caam_hash_algos get_hash_type(struct hash_algo *algo)
  46 +{
  47 + if (!strcmp(algo->name, driver_hash[SHA1].name))
  48 + return SHA1;
  49 + else
  50 + return SHA256;
  51 +}
  52 +
  53 +/* Create the context for progressive hashing using h/w acceleration.
  54 + *
  55 + * @ctxp: Pointer to the pointer of the context for hashing
  56 + * @caam_algo: Enum for SHA1 or SHA256
  57 + * @return 0 if ok, -ENOMEM on error
  58 + */
  59 +static int caam_hash_init(void **ctxp, enum caam_hash_algos caam_algo)
  60 +{
  61 + *ctxp = calloc(1, sizeof(struct sha_ctx));
  62 + if (*ctxp == NULL) {
  63 + debug("Cannot allocate memory for context\n");
  64 + return -ENOMEM;
  65 + }
  66 + return 0;
  67 +}
  68 +
  69 +/*
  70 + * Update sg table for progressive hashing using h/w acceleration
  71 + *
  72 + * The context is freed by this function if an error occurs.
  73 + * We support at most 32 Scatter/Gather Entries.
  74 + *
  75 + * @hash_ctx: Pointer to the context for hashing
  76 + * @buf: Pointer to the buffer being hashed
  77 + * @size: Size of the buffer being hashed
  78 + * @is_last: 1 if this is the last update; 0 otherwise
  79 + * @caam_algo: Enum for SHA1 or SHA256
  80 + * @return 0 if ok, -EINVAL on error
  81 + */
  82 +static int caam_hash_update(void *hash_ctx, const void *buf,
  83 + unsigned int size, int is_last,
  84 + enum caam_hash_algos caam_algo)
  85 +{
  86 + uint32_t final = 0;
  87 + dma_addr_t addr = virt_to_phys((void *)buf);
  88 + struct sha_ctx *ctx = hash_ctx;
  89 +
  90 + if (ctx->sg_num >= MAX_SG_32) {
  91 + free(ctx);
  92 + return -EINVAL;
  93 + }
  94 +
  95 +#ifdef CONFIG_PHYS_64BIT
  96 + ctx->sg_tbl[ctx->sg_num].addr_hi = addr >> 32;
  97 +#else
  98 + ctx->sg_tbl[ctx->sg_num].addr_hi = 0x0;
  99 +#endif
  100 + ctx->sg_tbl[ctx->sg_num].addr_lo = addr;
  101 +
  102 + sec_out32(&ctx->sg_tbl[ctx->sg_num].len_flag,
  103 + (size & SG_ENTRY_LENGTH_MASK));
  104 +
  105 + ctx->sg_num++;
  106 +
  107 + if (is_last) {
  108 + final = sec_in32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag) |
  109 + SG_ENTRY_FINAL_BIT;
  110 + sec_out32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag, final);
  111 + }
  112 +
  113 + return 0;
  114 +}
  115 +
  116 +/*
  117 + * Perform progressive hashing on the given buffer and copy hash at
  118 + * destination buffer
  119 + *
  120 + * The context is freed after completion of hash operation.
  121 + *
  122 + * @hash_ctx: Pointer to the context for hashing
  123 + * @dest_buf: Pointer to the destination buffer where hash is to be copied
  124 + * @size: Size of the buffer being hashed
  125 + * @caam_algo: Enum for SHA1 or SHA256
  126 + * @return 0 if ok, -EINVAL on error
  127 + */
  128 +static int caam_hash_finish(void *hash_ctx, void *dest_buf,
  129 + int size, enum caam_hash_algos caam_algo)
  130 +{
  131 + uint32_t len = 0;
  132 + struct sha_ctx *ctx = hash_ctx;
  133 + int i = 0, ret = 0;
  134 +
  135 + if (size < driver_hash[caam_algo].digestsize) {
  136 + free(ctx);
  137 + return -EINVAL;
  138 + }
  139 +
  140 + for (i = 0; i < ctx->sg_num; i++)
  141 + len += (sec_in32(&ctx->sg_tbl[i].len_flag) &
  142 + SG_ENTRY_LENGTH_MASK);
  143 +
  144 + inline_cnstr_jobdesc_hash(ctx->sha_desc, (uint8_t *)ctx->sg_tbl, len,
  145 + ctx->hash,
  146 + driver_hash[caam_algo].alg_type,
  147 + driver_hash[caam_algo].digestsize,
  148 + 1);
  149 +
  150 + ret = run_descriptor_jr(ctx->sha_desc);
  151 +
  152 + if (ret)
  153 + debug("Error %x\n", ret);
  154 + else
  155 + memcpy(dest_buf, ctx->hash, sizeof(ctx->hash));
  156 +
  157 + free(ctx);
  158 + return ret;
  159 +}
  160 +
42 161 int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
43 162 unsigned char *pout, enum caam_hash_algos algo)
44 163 {
... ... @@ -48,7 +167,7 @@
48 167 desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
49 168 if (!desc) {
50 169 debug("Not enough memory for descriptor allocation\n");
51   - return -1;
  170 + return -ENOMEM;
52 171 }
53 172  
54 173 inline_cnstr_jobdesc_hash(desc, pbuf, buf_len, pout,
... ... @@ -74,5 +193,22 @@
74 193 {
75 194 if (caam_hash(pbuf, buf_len, pout, SHA1))
76 195 printf("CAAM was not setup properly or it is faulty\n");
  196 +}
  197 +
  198 +int hw_sha_init(struct hash_algo *algo, void **ctxp)
  199 +{
  200 + return caam_hash_init(ctxp, get_hash_type(algo));
  201 +}
  202 +
  203 +int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
  204 + unsigned int size, int is_last)
  205 +{
  206 + return caam_hash_update(ctx, buf, size, is_last, get_hash_type(algo));
  207 +}
  208 +
  209 +int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf,
  210 + int size)
  211 +{
  212 + return caam_hash_finish(ctx, dest_buf, size, get_hash_type(algo));
77 213 }
drivers/crypto/fsl/fsl_hash.h
  1 +/*
  2 + * Copyright 2014 Freescale Semiconductor, Inc.
  3 + *
  4 + * SPDX-License-Identifier: GPL-2.0+
  5 + *
  6 + */
  7 +
  8 +#ifndef _SHA_H
  9 +#define _SHA_H
  10 +
  11 +#include <fsl_sec.h>
  12 +#include <hash.h>
  13 +#include "jr.h"
  14 +
  15 +/* We support at most 32 Scatter/Gather Entries.*/
  16 +#define MAX_SG_32 32
  17 +
  18 +/*
  19 + * Hash context contains the following fields
  20 + * @sha_desc: Sha Descriptor
  21 + * @sg_num: number of entries in sg table
  22 + * @len: total length of buffer
  23 + * @sg_tbl: sg entry table
  24 + * @hash: index to the hash calculated
  25 + */
  26 +struct sha_ctx {
  27 + uint32_t sha_desc[64];
  28 + uint32_t sg_num;
  29 + uint32_t len;
  30 + struct sg_entry sg_tbl[MAX_SG_32];
  31 + u8 hash[HASH_MAX_DIGEST_SIZE];
  32 +};
  33 +
  34 +#endif
... ... @@ -175,6 +175,32 @@
175 175 u32 jrcr;
176 176 };
177 177  
  178 +/*
  179 + * Scatter Gather Entry - Specifies the the Scatter Gather Format
  180 + * related information
  181 + */
  182 +struct sg_entry {
  183 +#ifdef CONFIG_SYS_FSL_SEC_LE
  184 + uint32_t addr_lo; /* Memory Address - lo */
  185 + uint16_t addr_hi; /* Memory Address of start of buffer - hi */
  186 + uint16_t reserved_zero;
  187 +#else
  188 + uint16_t reserved_zero;
  189 + uint16_t addr_hi; /* Memory Address of start of buffer - hi */
  190 + uint32_t addr_lo; /* Memory Address - lo */
  191 +#endif
  192 +
  193 + uint32_t len_flag; /* Length of the data in the frame */
  194 +#define SG_ENTRY_LENGTH_MASK 0x3FFFFFFF
  195 +#define SG_ENTRY_EXTENSION_BIT 0x80000000
  196 +#define SG_ENTRY_FINAL_BIT 0x40000000
  197 + uint32_t bpid_offset;
  198 +#define SG_ENTRY_BPID_MASK 0x00FF0000
  199 +#define SG_ENTRY_BPID_SHIFT 16
  200 +#define SG_ENTRY_OFFSET_MASK 0x00001FFF
  201 +#define SG_ENTRY_OFFSET_SHIFT 0
  202 +};
  203 +
178 204 int sec_init(void);
179 205 #endif
180 206  
... ... @@ -7,8 +7,8 @@
7 7 */
8 8 #ifndef __HW_SHA_H
9 9 #define __HW_SHA_H
  10 +#include <hash.h>
10 11  
11   -
12 12 /**
13 13 * Computes hash value of input pbuf using h/w acceleration
14 14 *
... ... @@ -34,5 +34,44 @@
34 34 */
35 35 void hw_sha1(const uchar * in_addr, uint buflen,
36 36 uchar * out_addr, uint chunk_size);
  37 +
  38 +/*
  39 + * Create the context for sha progressive hashing using h/w acceleration
  40 + *
  41 + * @algo: Pointer to the hash_algo struct
  42 + * @ctxp: Pointer to the pointer of the context for hashing
  43 + * @return 0 if ok, -ve on error
  44 + */
  45 +int hw_sha_init(struct hash_algo *algo, void **ctxp);
  46 +
  47 +/*
  48 + * Update buffer for sha progressive hashing using h/w acceleration
  49 + *
  50 + * The context is freed by this function if an error occurs.
  51 + *
  52 + * @algo: Pointer to the hash_algo struct
  53 + * @ctx: Pointer to the context for hashing
  54 + * @buf: Pointer to the buffer being hashed
  55 + * @size: Size of the buffer being hashed
  56 + * @is_last: 1 if this is the last update; 0 otherwise
  57 + * @return 0 if ok, -ve on error
  58 + */
  59 +int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
  60 + unsigned int size, int is_last);
  61 +
  62 +/*
  63 + * Copy sha hash result at destination location
  64 + *
  65 + * The context is freed after completion of hash operation or after an error.
  66 + *
  67 + * @algo: Pointer to the hash_algo struct
  68 + * @ctx: Pointer to the context for hashing
  69 + * @dest_buf: Pointer to the destination buffer where hash is to be copied
  70 + * @size: Size of the buffer being hashed
  71 + * @return 0 if ok, -ve on error
  72 + */
  73 +int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf,
  74 + int size);
  75 +
37 76 #endif
... ... @@ -29,5 +29,41 @@
29 29  
30 30 source lib/rsa/Kconfig
31 31  
  32 +menu "Hashing Support"
  33 +
  34 +config SHA1
  35 + bool "Enable SHA1 support"
  36 + help
  37 + This option enables support of hashing using SHA1 algorithm.
  38 + The hash is calculated in software.
  39 + The SHA1 algorithm produces a 160-bit (20-byte) hash value
  40 + (digest).
  41 +
  42 +config SHA256
  43 + bool "Enable SHA256 support"
  44 + help
  45 + This option enables support of hashing using SHA256 algorithm.
  46 + The hash is calculated in software.
  47 + The SHA256 algorithm produces a 256-bit (32-byte) hash value
  48 + (digest).
  49 +
  50 +config SHA_HW_ACCEL
  51 + bool "Enable hashing using hardware"
  52 + help
  53 + This option enables hardware acceleration
  54 + for SHA1/SHA256 hashing.
  55 + This affects the 'hash' command and also the
  56 + hash_lookup_algo() function.
  57 +
  58 +config SHA_PROG_HW_ACCEL
  59 + bool "Enable Progressive hashing support using hardware"
  60 + depends on SHA_HW_ACCEL
  61 + help
  62 + This option enables hardware-acceleration for
  63 + SHA1/SHA256 progressive hashing.
  64 + Data can be streamed in a block at a time and the hashing
  65 + is performed in hardware.
  66 +endmenu
  67 +
32 68 endmenu