aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLee Nipper <lee.nipper@gmail.com>2011-11-21 03:13:25 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2011-11-21 03:21:48 -0500
commit79b3a418e090248d00ceba40b81da9dfac753367 (patch)
tree99ac80d75596b08206e3397a632ff7df6b5ad015
parentd35643385628d44a5933a0755b01478eb4df5c65 (diff)
crypto: talitos - add hmac algorithms
Add these hmac algorithms to talitos: hmac(md5), hmac(sha1), hmac(sha224), hmac(sha256), hmac(sha384), hmac(sha512). These are all type ahash. Signed-off-by: Lee Nipper <lee.nipper@gmail.com> Fixed up to not register HMAC algorithms on sec2.0 devices. Rationale (from Lee): on an 8349E Rev1.1, there's a problem with hmac for any talitos hmac sequence requiring an intermediate hash context (Pointer DWORD 1); the result is an incorrect hmac. An intermediate hash context is required for something longer than (65536-blocksize), and for other cases when update/finup/final are used inefficiently. Interestingly, a normal hash (without hmac) works perfectly when using an intermediate context. Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/talitos.c237
1 files changed, 235 insertions, 2 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dbe76b5df9cf..8ce87317310b 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -157,6 +157,7 @@ struct talitos_private {
157#define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001 157#define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001
158#define TALITOS_FTR_HW_AUTH_CHECK 0x00000002 158#define TALITOS_FTR_HW_AUTH_CHECK 0x00000002
159#define TALITOS_FTR_SHA224_HWINIT 0x00000004 159#define TALITOS_FTR_SHA224_HWINIT 0x00000004
160#define TALITOS_FTR_HMAC_OK 0x00000008
160 161
161static void to_talitos_ptr(struct talitos_ptr *talitos_ptr, dma_addr_t dma_addr) 162static void to_talitos_ptr(struct talitos_ptr *talitos_ptr, dma_addr_t dma_addr)
162{ 163{
@@ -1874,6 +1875,97 @@ static int ahash_digest(struct ahash_request *areq)
1874 return ahash_process_req(areq, areq->nbytes); 1875 return ahash_process_req(areq, areq->nbytes);
1875} 1876}
1876 1877
1878struct keyhash_result {
1879 struct completion completion;
1880 int err;
1881};
1882
1883static void keyhash_complete(struct crypto_async_request *req, int err)
1884{
1885 struct keyhash_result *res = req->data;
1886
1887 if (err == -EINPROGRESS)
1888 return;
1889
1890 res->err = err;
1891 complete(&res->completion);
1892}
1893
1894static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen,
1895 u8 *hash)
1896{
1897 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
1898
1899 struct scatterlist sg[1];
1900 struct ahash_request *req;
1901 struct keyhash_result hresult;
1902 int ret;
1903
1904 init_completion(&hresult.completion);
1905
1906 req = ahash_request_alloc(tfm, GFP_KERNEL);
1907 if (!req)
1908 return -ENOMEM;
1909
1910 /* Keep tfm keylen == 0 during hash of the long key */
1911 ctx->keylen = 0;
1912 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
1913 keyhash_complete, &hresult);
1914
1915 sg_init_one(&sg[0], key, keylen);
1916
1917 ahash_request_set_crypt(req, sg, hash, keylen);
1918 ret = crypto_ahash_digest(req);
1919 switch (ret) {
1920 case 0:
1921 break;
1922 case -EINPROGRESS:
1923 case -EBUSY:
1924 ret = wait_for_completion_interruptible(
1925 &hresult.completion);
1926 if (!ret)
1927 ret = hresult.err;
1928 break;
1929 default:
1930 break;
1931 }
1932 ahash_request_free(req);
1933
1934 return ret;
1935}
1936
1937static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
1938 unsigned int keylen)
1939{
1940 struct talitos_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
1941 unsigned int blocksize =
1942 crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
1943 unsigned int digestsize = crypto_ahash_digestsize(tfm);
1944 unsigned int keysize = keylen;
1945 u8 hash[SHA512_DIGEST_SIZE];
1946 int ret;
1947
1948 if (keylen <= blocksize)
1949 memcpy(ctx->key, key, keysize);
1950 else {
1951 /* Must get the hash of the long key */
1952 ret = keyhash(tfm, key, keylen, hash);
1953
1954 if (ret) {
1955 crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
1956 return -EINVAL;
1957 }
1958
1959 keysize = digestsize;
1960 memcpy(ctx->key, hash, digestsize);
1961 }
1962
1963 ctx->keylen = keysize;
1964
1965 return 0;
1966}
1967
1968
1877struct talitos_alg_template { 1969struct talitos_alg_template {
1878 u32 type; 1970 u32 type;
1879 union { 1971 union {
@@ -2217,6 +2309,138 @@ static struct talitos_alg_template driver_algs[] = {
2217 DESC_HDR_SEL0_MDEUB | 2309 DESC_HDR_SEL0_MDEUB |
2218 DESC_HDR_MODE0_MDEUB_SHA512, 2310 DESC_HDR_MODE0_MDEUB_SHA512,
2219 }, 2311 },
2312 { .type = CRYPTO_ALG_TYPE_AHASH,
2313 .alg.hash = {
2314 .init = ahash_init,
2315 .update = ahash_update,
2316 .final = ahash_final,
2317 .finup = ahash_finup,
2318 .digest = ahash_digest,
2319 .setkey = ahash_setkey,
2320 .halg.digestsize = MD5_DIGEST_SIZE,
2321 .halg.base = {
2322 .cra_name = "hmac(md5)",
2323 .cra_driver_name = "hmac-md5-talitos",
2324 .cra_blocksize = MD5_BLOCK_SIZE,
2325 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2326 CRYPTO_ALG_ASYNC,
2327 .cra_type = &crypto_ahash_type
2328 }
2329 },
2330 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2331 DESC_HDR_SEL0_MDEUA |
2332 DESC_HDR_MODE0_MDEU_MD5,
2333 },
2334 { .type = CRYPTO_ALG_TYPE_AHASH,
2335 .alg.hash = {
2336 .init = ahash_init,
2337 .update = ahash_update,
2338 .final = ahash_final,
2339 .finup = ahash_finup,
2340 .digest = ahash_digest,
2341 .setkey = ahash_setkey,
2342 .halg.digestsize = SHA1_DIGEST_SIZE,
2343 .halg.base = {
2344 .cra_name = "hmac(sha1)",
2345 .cra_driver_name = "hmac-sha1-talitos",
2346 .cra_blocksize = SHA1_BLOCK_SIZE,
2347 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2348 CRYPTO_ALG_ASYNC,
2349 .cra_type = &crypto_ahash_type
2350 }
2351 },
2352 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2353 DESC_HDR_SEL0_MDEUA |
2354 DESC_HDR_MODE0_MDEU_SHA1,
2355 },
2356 { .type = CRYPTO_ALG_TYPE_AHASH,
2357 .alg.hash = {
2358 .init = ahash_init,
2359 .update = ahash_update,
2360 .final = ahash_final,
2361 .finup = ahash_finup,
2362 .digest = ahash_digest,
2363 .setkey = ahash_setkey,
2364 .halg.digestsize = SHA224_DIGEST_SIZE,
2365 .halg.base = {
2366 .cra_name = "hmac(sha224)",
2367 .cra_driver_name = "hmac-sha224-talitos",
2368 .cra_blocksize = SHA224_BLOCK_SIZE,
2369 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2370 CRYPTO_ALG_ASYNC,
2371 .cra_type = &crypto_ahash_type
2372 }
2373 },
2374 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2375 DESC_HDR_SEL0_MDEUA |
2376 DESC_HDR_MODE0_MDEU_SHA224,
2377 },
2378 { .type = CRYPTO_ALG_TYPE_AHASH,
2379 .alg.hash = {
2380 .init = ahash_init,
2381 .update = ahash_update,
2382 .final = ahash_final,
2383 .finup = ahash_finup,
2384 .digest = ahash_digest,
2385 .setkey = ahash_setkey,
2386 .halg.digestsize = SHA256_DIGEST_SIZE,
2387 .halg.base = {
2388 .cra_name = "hmac(sha256)",
2389 .cra_driver_name = "hmac-sha256-talitos",
2390 .cra_blocksize = SHA256_BLOCK_SIZE,
2391 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2392 CRYPTO_ALG_ASYNC,
2393 .cra_type = &crypto_ahash_type
2394 }
2395 },
2396 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2397 DESC_HDR_SEL0_MDEUA |
2398 DESC_HDR_MODE0_MDEU_SHA256,
2399 },
2400 { .type = CRYPTO_ALG_TYPE_AHASH,
2401 .alg.hash = {
2402 .init = ahash_init,
2403 .update = ahash_update,
2404 .final = ahash_final,
2405 .finup = ahash_finup,
2406 .digest = ahash_digest,
2407 .setkey = ahash_setkey,
2408 .halg.digestsize = SHA384_DIGEST_SIZE,
2409 .halg.base = {
2410 .cra_name = "hmac(sha384)",
2411 .cra_driver_name = "hmac-sha384-talitos",
2412 .cra_blocksize = SHA384_BLOCK_SIZE,
2413 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2414 CRYPTO_ALG_ASYNC,
2415 .cra_type = &crypto_ahash_type
2416 }
2417 },
2418 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2419 DESC_HDR_SEL0_MDEUB |
2420 DESC_HDR_MODE0_MDEUB_SHA384,
2421 },
2422 { .type = CRYPTO_ALG_TYPE_AHASH,
2423 .alg.hash = {
2424 .init = ahash_init,
2425 .update = ahash_update,
2426 .final = ahash_final,
2427 .finup = ahash_finup,
2428 .digest = ahash_digest,
2429 .setkey = ahash_setkey,
2430 .halg.digestsize = SHA512_DIGEST_SIZE,
2431 .halg.base = {
2432 .cra_name = "hmac(sha512)",
2433 .cra_driver_name = "hmac-sha512-talitos",
2434 .cra_blocksize = SHA512_BLOCK_SIZE,
2435 .cra_flags = CRYPTO_ALG_TYPE_AHASH |
2436 CRYPTO_ALG_ASYNC,
2437 .cra_type = &crypto_ahash_type
2438 }
2439 },
2440 .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
2441 DESC_HDR_SEL0_MDEUB |
2442 DESC_HDR_MODE0_MDEUB_SHA512,
2443 }
2220}; 2444};
2221 2445
2222struct talitos_crypto_alg { 2446struct talitos_crypto_alg {
@@ -2373,8 +2597,12 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
2373 case CRYPTO_ALG_TYPE_AHASH: 2597 case CRYPTO_ALG_TYPE_AHASH:
2374 alg = &t_alg->algt.alg.hash.halg.base; 2598 alg = &t_alg->algt.alg.hash.halg.base;
2375 alg->cra_init = talitos_cra_init_ahash; 2599 alg->cra_init = talitos_cra_init_ahash;
2600 if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
2601 !strncmp(alg->cra_name, "hmac", 4))
2602 return ERR_PTR(-ENOTSUPP);
2376 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) && 2603 if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
2377 !strcmp(alg->cra_name, "sha224")) { 2604 (!strcmp(alg->cra_name, "sha224") ||
2605 !strcmp(alg->cra_name, "hmac(sha224)"))) {
2378 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit; 2606 t_alg->algt.alg.hash.init = ahash_init_sha224_swinit;
2379 t_alg->algt.desc_hdr_template = 2607 t_alg->algt.desc_hdr_template =
2380 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | 2608 DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
@@ -2471,7 +2699,8 @@ static int talitos_probe(struct platform_device *ofdev)
2471 2699
2472 if (of_device_is_compatible(np, "fsl,sec2.1")) 2700 if (of_device_is_compatible(np, "fsl,sec2.1"))
2473 priv->features |= TALITOS_FTR_HW_AUTH_CHECK | 2701 priv->features |= TALITOS_FTR_HW_AUTH_CHECK |
2474 TALITOS_FTR_SHA224_HWINIT; 2702 TALITOS_FTR_SHA224_HWINIT |
2703 TALITOS_FTR_HMAC_OK;
2475 2704
2476 priv->chan = kzalloc(sizeof(struct talitos_channel) * 2705 priv->chan = kzalloc(sizeof(struct talitos_channel) *
2477 priv->num_channels, GFP_KERNEL); 2706 priv->num_channels, GFP_KERNEL);
@@ -2530,6 +2759,10 @@ static int talitos_probe(struct platform_device *ofdev)
2530 t_alg = talitos_alg_alloc(dev, &driver_algs[i]); 2759 t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
2531 if (IS_ERR(t_alg)) { 2760 if (IS_ERR(t_alg)) {
2532 err = PTR_ERR(t_alg); 2761 err = PTR_ERR(t_alg);
2762 if (err == -ENOTSUPP) {
2763 kfree(t_alg);
2764 continue;
2765 }
2533 goto err_out; 2766 goto err_out;
2534 } 2767 }
2535 2768