Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: talitos - add support for sha224

SEC h/w versions 2.1 and above support sha224 via explicit instruction.

Performing sha224 ahashes on earlier versions is still possible because
they support sha256 (sha224 is sha256 with different initial constants
and a different truncation length). We do this by overriding hardware
context self-initialization, and perform it manually in s/w instead.

Thanks to Lee for his fixes for correct execution on actual sec2.0 h/w.

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off by: Lee Nipper <lee.nipper@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Kim Phillips and committed by
Herbert Xu
60f208d7 497f2e6b

+75 -10
+72 -9
drivers/crypto/talitos.c
··· 1 1 /* 2 2 * talitos - Freescale Integrated Security Engine (SEC) device driver 3 3 * 4 - * Copyright (c) 2008 Freescale Semiconductor, Inc. 4 + * Copyright (c) 2008-2010 Freescale Semiconductor, Inc. 5 5 * 6 6 * Scatterlist Crypto API glue code copied from files with the following: 7 7 * Copyright (c) 2006-2007 Herbert Xu <herbert@gondor.apana.org.au> ··· 156 156 /* .features flag */ 157 157 #define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001 158 158 #define TALITOS_FTR_HW_AUTH_CHECK 0x00000002 159 + #define TALITOS_FTR_SHA224_HWINIT 0x00000004 159 160 160 161 static void to_talitos_ptr(struct talitos_ptr *talitos_ptr, dma_addr_t dma_addr) 161 162 { ··· 721 720 722 721 struct talitos_ahash_req_ctx { 723 722 u64 count; 724 - u8 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE]; 723 + u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)]; 725 724 unsigned int hw_context_size; 726 725 u8 buf[HASH_MAX_BLOCK_SIZE]; 727 726 u8 bufnext[HASH_MAX_BLOCK_SIZE]; 727 + unsigned int swinit; 728 728 unsigned int first; 729 729 unsigned int last; 730 730 unsigned int to_hash_later; ··· 1633 1631 /* first DWORD empty */ 1634 1632 desc->ptr[0] = zero_entry; 1635 1633 1636 - /* hash context in (if not first) */ 1637 - if (!req_ctx->first) { 1634 + /* hash context in */ 1635 + if (!req_ctx->first || req_ctx->swinit) { 1638 1636 map_single_talitos_ptr(dev, &desc->ptr[1], 1639 1637 req_ctx->hw_context_size, 1640 1638 (char *)req_ctx->hw_context, 0, 1641 1639 DMA_TO_DEVICE); 1640 + req_ctx->swinit = 0; 1642 1641 } else { 1643 1642 desc->ptr[1] = zero_entry; 1644 1643 /* Indicate next op is not the first. */ ··· 1725 1722 1726 1723 /* Initialize the context */ 1727 1724 req_ctx->count = 0; 1728 - req_ctx->first = 1; /* first indicates h/w must init it's context */ 1725 + req_ctx->first = 1; /* first indicates h/w must init its context */ 1726 + req_ctx->swinit = 0; /* assume h/w init of context */ 1729 1727 req_ctx->hw_context_size = 1730 1728 (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE) 1731 1729 ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256 1732 1730 : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512; 1731 + 1732 + return 0; 1733 + } 1734 + 1735 + /* 1736 + * on h/w without explicit sha224 support, we initialize h/w context 1737 + * manually with sha224 constants, and tell it to run sha256. 1738 + */ 1739 + static int ahash_init_sha224_swinit(struct ahash_request *areq) 1740 + { 1741 + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 1742 + 1743 + ahash_init(areq); 1744 + req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/ 1745 + 1746 + req_ctx->hw_context[0] = cpu_to_be32(SHA224_H0); 1747 + req_ctx->hw_context[1] = cpu_to_be32(SHA224_H1); 1748 + req_ctx->hw_context[2] = cpu_to_be32(SHA224_H2); 1749 + req_ctx->hw_context[3] = cpu_to_be32(SHA224_H3); 1750 + req_ctx->hw_context[4] = cpu_to_be32(SHA224_H4); 1751 + req_ctx->hw_context[5] = cpu_to_be32(SHA224_H5); 1752 + req_ctx->hw_context[6] = cpu_to_be32(SHA224_H6); 1753 + req_ctx->hw_context[7] = cpu_to_be32(SHA224_H7); 1754 + 1755 + /* init 64-bit count */ 1756 + req_ctx->hw_context[8] = 0; 1757 + req_ctx->hw_context[9] = 0; 1733 1758 1734 1759 return 0; 1735 1760 } ··· 1830 1799 else 1831 1800 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT; 1832 1801 1833 - /* On first one, request SEC to INIT hash. */ 1834 - if (req_ctx->first) 1802 + /* request SEC to INIT hash. */ 1803 + if (req_ctx->first && !req_ctx->swinit) 1835 1804 edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT; 1836 1805 1837 1806 /* When the tfm context has a keylen, it's an HMAC. ··· 1874 1843 static int ahash_digest(struct ahash_request *areq) 1875 1844 { 1876 1845 struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); 1846 + struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq); 1877 1847 1878 - ahash_init(areq); 1848 + ahash->init(areq); 1879 1849 req_ctx->last = 1; 1880 1850 1881 1851 return ahash_process_req(areq, areq->nbytes); ··· 2148 2116 .final = ahash_final, 2149 2117 .finup = ahash_finup, 2150 2118 .digest = ahash_digest, 2119 + .halg.digestsize = SHA224_DIGEST_SIZE, 2120 + .halg.base = { 2121 + .cra_name = "sha224", 2122 + .cra_driver_name = "sha224-talitos", 2123 + .cra_blocksize = SHA224_BLOCK_SIZE, 2124 + .cra_flags = CRYPTO_ALG_TYPE_AHASH | 2125 + CRYPTO_ALG_ASYNC, 2126 + .cra_type = &crypto_ahash_type 2127 + } 2128 + }, 2129 + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 2130 + DESC_HDR_SEL0_MDEUA | 2131 + DESC_HDR_MODE0_MDEU_SHA224, 2132 + }, 2133 + { .type = CRYPTO_ALG_TYPE_AHASH, 2134 + .alg.hash = { 2135 + .init = ahash_init, 2136 + .update = ahash_update, 2137 + .final = ahash_final, 2138 + .finup = ahash_finup, 2139 + .digest = ahash_digest, 2151 2140 .halg.digestsize = SHA256_DIGEST_SIZE, 2152 2141 .halg.base = { 2153 2142 .cra_name = "sha256", ··· 2351 2298 struct talitos_alg_template 2352 2299 *template) 2353 2300 { 2301 + struct talitos_private *priv = dev_get_drvdata(dev); 2354 2302 struct talitos_crypto_alg *t_alg; 2355 2303 struct crypto_alg *alg; 2356 2304 ··· 2373 2319 case CRYPTO_ALG_TYPE_AHASH: 2374 2320 alg = &t_alg->algt.alg.hash.halg.base; 2375 2321 alg->cra_init = talitos_cra_init_ahash; 2322 + if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) && 2323 + !strcmp(alg->cra_name, "sha224")) { 2324 + t_alg->algt.alg.hash.init = ahash_init_sha224_swinit; 2325 + t_alg->algt.desc_hdr_template = 2326 + DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 2327 + DESC_HDR_SEL0_MDEUA | 2328 + DESC_HDR_MODE0_MDEU_SHA256; 2329 + } 2376 2330 break; 2377 2331 } 2378 2332 ··· 2468 2406 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT; 2469 2407 2470 2408 if (of_device_is_compatible(np, "fsl,sec2.1")) 2471 - priv->features |= TALITOS_FTR_HW_AUTH_CHECK; 2409 + priv->features |= TALITOS_FTR_HW_AUTH_CHECK | 2410 + TALITOS_FTR_SHA224_HWINIT; 2472 2411 2473 2412 priv->chan = kzalloc(sizeof(struct talitos_channel) * 2474 2413 priv->num_channels, GFP_KERNEL);
+3 -1
drivers/crypto/talitos.h
··· 1 1 /* 2 2 * Freescale SEC (talitos) device register and descriptor header defines 3 3 * 4 - * Copyright (c) 2006-2008 Freescale Semiconductor, Inc. 4 + * Copyright (c) 2006-2010 Freescale Semiconductor, Inc. 5 5 * 6 6 * Redistribution and use in source and binary forms, with or without 7 7 * modification, are permitted provided that the following conditions ··· 164 164 #define DESC_HDR_MODE0_MDEU_INIT cpu_to_be32(0x01000000) 165 165 #define DESC_HDR_MODE0_MDEU_HMAC cpu_to_be32(0x00800000) 166 166 #define DESC_HDR_MODE0_MDEU_PAD cpu_to_be32(0x00400000) 167 + #define DESC_HDR_MODE0_MDEU_SHA224 cpu_to_be32(0x00300000) 167 168 #define DESC_HDR_MODE0_MDEU_MD5 cpu_to_be32(0x00200000) 168 169 #define DESC_HDR_MODE0_MDEU_SHA256 cpu_to_be32(0x00100000) 169 170 #define DESC_HDR_MODE0_MDEU_SHA1 cpu_to_be32(0x00000000) ··· 188 187 #define DESC_HDR_MODE1_MDEU_INIT cpu_to_be32(0x00001000) 189 188 #define DESC_HDR_MODE1_MDEU_HMAC cpu_to_be32(0x00000800) 190 189 #define DESC_HDR_MODE1_MDEU_PAD cpu_to_be32(0x00000400) 190 + #define DESC_HDR_MODE1_MDEU_SHA224 cpu_to_be32(0x00000300) 191 191 #define DESC_HDR_MODE1_MDEU_MD5 cpu_to_be32(0x00000200) 192 192 #define DESC_HDR_MODE1_MDEU_SHA256 cpu_to_be32(0x00000100) 193 193 #define DESC_HDR_MODE1_MDEU_SHA1 cpu_to_be32(0x00000000)